﻿#ifndef __SS_STRING_H__
#define __SS_STRING_H__
#include "ssStrfunc.h"
#include "../container/ssArray.h"
#include "../algorithms/ssKMP.h"
#include "../dump/ssException.h"


namespace StarSeeker
{

template<typename T>
class ssStringBase
{
public:
	typedef ssArray<ssStringBase<T> > StrElements_t;
	typedef ssArray<StrElements_t> StrElementList_t;

	ssStringBase() :m_string(0), m_strLen(0), m_maxLen(0)
	{
		GetType();
	}
	ssStringBase(const u32 size) :m_string(0), m_strLen(0), m_maxLen(0)
	{
		GetType();
		SetBuffer(size, false);
	}
	ssStringBase(const T* s) :m_string(0), m_strLen(0), m_maxLen(0)
	{
		GetType();
		CopyFrom(s);
	}
	ssStringBase(const ssStringBase& s) :m_string(0), m_strLen(0), m_maxLen(0)
	{
		GetType();
		CopyFrom(s);
	}
	virtual ~ssStringBase()
	{
		if (m_string)
		{
			delete[] m_string;
			m_string = 0;
		}
		m_strLen = 0;
		m_maxLen = 0;
		m_type = 0;
	}

	//赋值
	void CopyFrom(const T* s, u32 len)
	{
		if (len > 0)
		{
			SetBuffer(len, false);
			SafeCopy(s, len, false);
		}
		else
		{
			Empty();
		}
	}
	void CopyFrom(const T* s)
	{
		u32 len = StrLen<T>(s);
		CopyFrom(s, len);
	}
	void CopyFrom(const ssStringBase& s)
	{
		CopyFrom(s.m_string, s.m_strLen);
	}
	void operator = (const T* s)
	{
		CopyFrom(s);
	}
	void operator = (const ssStringBase& s)
	{
		CopyFrom(s);
	}

	//追加到字符串末尾
	void Add(const T* s, u32 len)
	{
		if (len > 0)
		{
			SetBuffer(len, true);
			SafeCopy(s, len, true);
		}
	}
	void Add(const T* s)
	{
		u32 len = StrLen<T>(s);
		Add(s, len);
	}
	void Add(const ssStringBase& s)
	{
		Add(s.m_string, s.m_strLen);
	}
	//把数字追加到字符串末尾
	void Add(const i32 a)
	{
		T num[16] = { 0 };
		if (m_type == 1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 16, "%d", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 16, L"%d", a);
		else
			return;
		Add(num);
	}
	void Add(const u32 a)
	{
		T num[16] = { 0 };
		if(m_type==1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 16, "%u", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 16, L"%u", a);
		else
			return;
		Add(num);
	}
	void Add(const f32 a)
	{
		T num[32] = { 0 };
		if (m_type == 1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 31, "%f", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 31, L"%f", a);
		else
			return;
		Add(num);
	}
	void Add(const f64 a)
	{
		T num[32] = { 0 };
		if (m_type == 1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 31, "%f", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 31, L"%f", a);
		else
			return;
		num[31] = 0;
		Add(num);
	}
	void Add(const i64 a)
	{
		T num[24] = { 0 };
		if (m_type == 1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 24, "%lld", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 24, L"%lld", a);
		else
			return;
		Add(num);
	}
	void Add(const u64 a)
	{
		T num[24] = { 0 };
		if (m_type == 1)
			snprintf(SS_REINTERPRET_CAST(char*, num), 24, "%llu", a);
		else if (m_type == 2)
			snwprintf(SS_REINTERPRET_CAST(wchar_t*, num), 24, L"%llu", a);
		else
			return;
		Add(num);
	}
	void operator += (const T* s)
	{
		Add(s);
	}
	void operator += (const ssStringBase& s)
	{
		Add(s);
	}
	void operator += (const i32 a)
	{
		Add(a);
	}
	void operator += (const u32 a)
	{
		Add(a);
	}
	void operator += (const f32 a)
	{
		Add(a);
	}
	void operator += (const i64 a)
	{
		Add(a);
	}
	ssStringBase operator + (const T* s)
	{
		u32 len = StrLen<T>(s);
		ssStringBase ns(this->m_strLen + len + 2);
		ns.CopyFrom(*this);
		ns.Add(s, len);
		return ns;
	}
	ssStringBase operator + (const ssStringBase& s)
	{
		ssStringBase ns(this->m_strLen + s.m_strLen + 2);
		ns.CopyFrom(*this);
		ns.Add(s);
		return ns;
	}
	ssStringBase operator + (i32 a)
	{
		ssStringBase ns(this->m_strLen + 16);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}
	ssStringBase operator + (u32 a)
	{
		ssStringBase ns(this->m_strLen + 16);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}
	ssStringBase operator + (i64 a)
	{
		ssStringBase ns(this->m_strLen + 24);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}
	ssStringBase operator + (u64 a)
	{
		ssStringBase ns(this->m_strLen + 24);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}
	ssStringBase operator + (f32 a)
	{
		ssStringBase ns(this->m_strLen + 32);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}
	ssStringBase operator + (f64 a)
	{
		ssStringBase ns(this->m_strLen + 32);
		ns.CopyFrom(*this);
		ns.Add(a);
		return ns;
	}

	//转变成数字
	i32 ToInt32()
	{
		if (m_type == 1)
			return Str2Int32(m_string);
		else if (m_type == 2)
			return WStr2Int32((const wchar_t*)m_string);
		else
			return 0;
	}
	u32 ToUInt32()
	{
		if (m_type == 1)
			return Str2UInt32(m_string);
		else if (m_type == 2)
			return WStr2UInt32((const wchar_t*)m_string);
		else
			return 0;
	}
	i64 ToInt64()
	{
		if (m_type == 1)
			return Str2Int64(m_string);
		else if (m_type == 2)
			return WStr2Int64((const wchar_t*)m_string);
		else
			return 0;
	}
	u64 ToUInt64()
	{
		if (m_type == 1)
			return Str2UInt64(m_string);
		else if (m_type == 2)
			return WStr2UInt64((const wchar_t*)m_string);
		else
			return 0;
	}
	f32 ToFloat()
	{
		if (m_type == 1)
			return Str2Float(m_string);
		else if (m_type == 2)
			return WStr2Float((const wchar_t*)m_string);
		else
			return 0;
	}

	//比较，相同为true
	bool Compare(const T* s) const
	{
		u32 len = StrLen<T>(s);
		if (len==m_strLen)
		{
			for (u32 i = 0; i < m_strLen; ++i)
			{
				if (m_string[i] != s[i])
				{
					return false;
				}
			}
			return true;
		}
		return false;
	}
	bool Compare(const ssStringBase& s) const
	{
		if (s.m_strLen == m_strLen)
		{
			for (u32 i = 0; i < m_strLen; ++i)
			{
				if (m_string[i] != s.m_string[i])
				{
					return false;
				}
			}
			return true;
		}
		return false;
	}
	bool operator == (const T *s)
	{
		return Compare(s);
	}
	bool operator == (const ssStringBase& s)
	{
		return Compare(s);
	}

	//字符串长度
	u32 Length() const
	{
		return m_strLen;
	}
	//字符串数组长度
	u32 Size() const
	{
		return m_strLen + 1;
	}
	//数组总长度
	u32 MaxSize() const
	{
		return m_maxLen;
	}
	//剩余空余长度
	u32 ResidueSize() const
	{
		return m_maxLen-m_strLen-1;
	}
	//字符串地址
	const T * GetString() const
	{
		return m_string;
	}
	//置空
	void Empty()
	{
		m_strLen = 0;
		if (m_string)
		{
			m_string[0] = 0;
		}
	}
	//格式化字符串，不安全的
	u32 Format(const T *param, ...)
	{
		if (m_string && m_maxLen > 0)
		{
			if (m_type != 1 && m_type != 2)
				return 0;

			va_list arglist;
			va_start(arglist, param);
			int len = 0;
			if (m_type == 1)
			{
				len = vsnprintf(SS_REINTERPRET_CAST(char*,m_string), m_maxLen - 1, SS_REINTERPRET_CAST(const char*,param), arglist);
			}
			else if (m_type == 2)
			{
				len = vsnwprintf(SS_REINTERPRET_CAST(wchar_t*,m_string), m_maxLen - 1, SS_REINTERPRET_CAST(const wchar_t*,param), arglist);
			}
			va_end(arglist);
			if (len > 0)
			{
				m_strLen = SS_STATIC_CAST(u32, len);
				return m_strLen;
			}
		}
		return 0;
	}
	//查找指定字符
	u32 FindChar(T c, u32 beginPos) const
	{
		for (u32 i = beginPos; i < m_strLen; ++i)
		{
			if (m_string[i] == c)
			{
				return i;
			}
		}
		return SS_INVAILD_U32;
	}
	//查找指定字符串
	u32 FindString(const T* str, u32 beginPos) const
	{
		if (beginPos < m_strLen)
		{
			return StringSearching(m_string + beginPos, m_strLen - beginPos, str, StrLen<T>(str));
		}
		return SS_INVAILD_U32;
	}
	//按范围获取子串
	ssStringBase<T> SubString(u32 beg, u32 len)
	{
		ssStringBase<T> sb;
		if (m_string && beg+len<=m_strLen)
		{
			sb.CopyFrom(m_string + beg, len);
		}
		return sb;
	}
	//剪裁字符串
	bool CutString(u32 beg, u32 len)
	{
		if (m_string && beg + len <= m_strLen)
		{
			memmove(m_string, m_string + beg, len);
			m_strLen = len;
			m_string[m_strLen] = 0;
			return true;
		}
		return false;
	}
	//按分隔符拆分字符串
	void StringSplit(const T* flag, StrElements_t& list)
	{
		ssStringBase<T> flagStr(flag);
		if (Length() > 1 && flagStr.Length()>0)
		{
			list.Empty();
			ssStringBase<T> tmpStr;
			u32 begin = 0;
			for (u32 i = 0; i <= Length(); ++i)
			{
				if (m_string[i] == flagStr[0] || m_string[i] == 0)
				{
					bool ok = true;
					for (u32 j = 0, k = i; j < flagStr.Length() && k < Length(); j++, k++)
					{
						if (flagStr[j]!=m_string[k])
						{
							ok = false;
							break;
						}
					}
					if (ok)
					{
						tmpStr.Empty();
						tmpStr = SubString(begin, i - begin);
						if (tmpStr.Length() > 0)
						{
							list.PushBack(tmpStr);
						}
						begin = i + flagStr.Length();
					}
				}
			}
		}
	}
	void StringSplit(T flag, StrElements_t& list)
	{
		if (Length() > 1)
		{
			list.Empty();
			ssStringBase<T> tmpStr;
			u32 begin = 0;
			for (u32 i = 0; i <= Length(); ++i)
			{
				if (m_string[i] == flag || m_string[i] == 0)
				{
					tmpStr.Empty();
					tmpStr = SubString(begin, i - begin);
					if (tmpStr.Length() > 0)
					{
						list.PushBack(tmpStr);
					}
					begin = i + 1;
				}
			}
		}
	}
	//按两级分隔符拆分字符串
	void StringSplit(T flag1, T flag2, StrElementList_t& list)
	{
		StrElements_t one;
		StrElements_t two;
		StringSplit(flag1, one);
		if (one.Count())
		{
			list.Empty();
			for (u32 i = 0; i < one.Count(); ++i)
			{
				two.Empty();
				one[i].StringSplit(flag2, two);
				list.PushBack(two);
			}
		}
	}
	//打印字符串
	void Print()
	{
		if (m_string)
		{
			if (m_type==1)
				printf("%s\n", SS_REINTERPRET_CAST(char*,m_string));
			else if (m_type == 2)
				wprintf(L"%ls\n", SS_REINTERPRET_CAST(wchar_t*,m_string));
		}
	}
	//单字符替换
	void CharReplace(T oldChar, T newChar)
	{
		for (u32 i = 0; i < m_strLen; ++i)
		{
			if (m_string[i] == oldChar)
			{
				m_string[i] = newChar;
			}
		}
	}
	//字符串替换
	void StringReplace(const T* oldStr, const T* newStr)
	{
		u32 oldLen = StrLen<T>(oldStr);
		u32 newLen = StrLen<T>(newStr);
		u32 pos = StringSearching(m_string, m_strLen, oldStr, oldLen);
		if (pos != SS_INVAILD_U32)
		{
			if (oldLen == newLen)
			{
				for (u32 i = 0; i < oldLen; ++i)
				{
					m_string[i] = newStr[i];
				}
			}
		}
	}
	//重置缓存大小
	bool  Resize(u32 newLen)
	{
		if (newLen*sizeof(T)<=SS_1GB)
		{
			SetBuffer(newLen, false);
			Empty();
			return true;
		}
		SS_THROW("str len too long");
		return false;
	}
	//数组访问
	T& operator [] (u32 offset) const
	{
		if (m_string && offset<m_maxLen)
		{
			return m_string[offset];
		}
		else
		{
			SS_THROW("[] out of range");
		}
	}
	//按下标访问内存
	const char* At(u32 offset) const
	{
		if (m_string && offset < m_maxLen)
		{
			return m_string + offset;
		}
		else
		{
			return 0;
		}
	}
	//指定数据长度
	bool SetLength(u32 len, bool add)
	{
		if (add)
		{
			if (m_strLen+len < m_maxLen)
			{
				m_strLen += len;
				return true;
			}
		}
		else
		{
			if (len < m_maxLen)
			{
				m_strLen = len;
				return true;
			}
		}
		return false;
	}
private:
	void SetBuffer(u32 num, bool add)
	{
		bool isnew = true;
		T* old = m_string;
		if (add)
		{
			num += m_strLen;
		}
		if (num==0 || num*sizeof(T) > SS_1GB)
		{
			SS_THROW("str len too long");
			return;
		}
		if (m_string)
		{
			if (m_maxLen > num)
				isnew = false;
		}
		if (isnew)
		{
			m_string = new T[num*2];
			m_maxLen = num*2;
			if (old)
			{
				if (add && m_strLen)
					memcpy(m_string, old, m_strLen*sizeof(T));

				delete[] old;
			}
		}
	}
	void SafeCopy(const T* s, u32 len, bool add)
	{
		if (m_string && s)
		{
			if (add)
			{
				if (m_maxLen > m_strLen+len)
				{
					memcpy(m_string+m_strLen, s, len*sizeof(T));
					m_strLen += len;
					m_string[m_strLen] = 0;
				}
			}
			else
			{
				if (m_maxLen>len)
				{
					memcpy(m_string, s, len*sizeof(T));
					m_string[len] = 0;
					m_strLen = len;
				}
			}
		}
	}
	u8 GetType()
	{
		if (sizeof(char) == sizeof(T))
			m_type = 1;
		else if (sizeof(wchar_t) == sizeof(T))
			m_type = 2;
		else if (sizeof(int) == sizeof(T))
			m_type = 3;
		return m_type;
	}

protected:
	T			*	m_string;			//数组地址
	u32				m_strLen;			//当前已用长度
	u32				m_maxLen;			//数组最大长度
	u8				m_type;				//类型1:char，2:wchar
};
typedef ssStringBase<char> ssString;
typedef ssStringBase<wchar_t> ssWString;

}
#endif
